﻿using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore.Metadata;
using NHibernate;
using System.Linq.Expressions;
using System.Text;

namespace Cyss.Core.Repository.NHibernate
{
    public partial class EfRepository<TEntity> : IRepository<TEntity> where TEntity : BaseEntity, new()
    {
        protected NHibernateContext _context;

        public EfRepository(NHibernateContext dbContext)
        {
            _context = dbContext;
        }

        protected ISession Session { get { return _context.Session; } }

        public IQueryable<TEntity> Table { get { return Session.Query<TEntity>(); } }

        public IQueryable<TEntity> TableNoTracking { get { return Session.Query<TEntity>(); } }

        public int BulkInsert(IEnumerable<TEntity> entities, Expression<Func<TEntity, object>> DistinctKeySelector = null)
        {
            throw new NotImplementedException();
        }

        public void BulkInsert(params IEnumerable<BaseEntity>[] entities)
        {
            throw new NotImplementedException();
        }

        public void BulkUpdate<K>(IEnumerable<TEntity> entities, Expression<Func<TEntity, K>> keySelector = null)
        {
            throw new NotImplementedException();
        }

        public void Delete(TEntity entity, bool IsSubmit = true)
        {
            
            Session.Delete(entity);
            Session.Flush();
        }

        public void Delete(IEnumerable<TEntity> entities, bool IsSubmit = true)
        {
            Session.Delete(entities);
            Session.Flush();
        }

        public void Delete(int Id)
        {
            string strSql = $"from [{typeof(TEntity).Name}] where Id='{Id}'";
            Session.Delete(strSql);
            Session.Flush();
        }

        public void Delete(IEnumerable<int> Ids)
        {
            string strSql = $"from [{typeof(TEntity).Name}] where Id in ({ToWhereString(Ids)}) ";
            Session.Delete(strSql);
            Session.Flush();
        }

        public async Task DeleteAsync(TEntity entity, bool IsSubmit = true)
        {
            await Session.DeleteAsync(entity);
            await Session.FlushAsync();
        }

        public async Task DeleteAsync(IEnumerable<TEntity> entities, bool IsSubmit = true)
        {
            await Session.DeleteAsync(entities);
            await Session.FlushAsync();
        }

        public void Delete(Expression<Func<TEntity, bool>> predicate)
        {
            throw new NotImplementedException();
        }

        public int ExecuteSqlCommand(string sql)
        {
            throw new NotImplementedException();
        }

        public Task<int> ExecuteSqlCommandAsync(string sql)
        {
            throw new NotImplementedException();
        }

        public TEntity GetById(object id)
        {
            return Session.Get<TEntity>(id);
        }

        public IEnumerable<IProperty> GetModifiedProperties(TEntity entity)
        {
            throw new NotImplementedException();
        }

        public void Insert(TEntity entity, bool IsSubmit = true)
        {
            int newid = (int)Session.Save(entity);
            Session.Flush();
        }

        public void Insert(IEnumerable<TEntity> entities, bool IsSubmit = true)
        {
            Session.Save(entities);
            Session.Flush();
        }

        public async Task<int> InsertAsync(TEntity entity, bool IsSubmit = true)
        {
            int newid = (int)(await Session.SaveAsync(entity));
            await Session.FlushAsync();
            return newid;
        }

        public async Task<int> InsertAsync(IEnumerable<TEntity> entities, bool IsSubmit = true)
        {
            int newid = (int)(await Session.SaveAsync(entities));
            await Session.FlushAsync();
            return newid;
        }

        public bool IsModified(TEntity entity, params string[] ProNames)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<T> Query<T>(string Sql, params SqlParameter[] cmdParms) where T : class, new()
        {
            throw new NotImplementedException();
        }

        public IEnumerable<T> Query<T>(Expression<Func<T, bool>> predicate = null) where T : class, new()
        {
            return Session.Query<T>().Where(predicate).ToList();
        }

        public void Update(TEntity entity, bool IsSubmit = true)
        {
            Session.Update(entity);
            Session.Flush();
        }

        public void Update(IEnumerable<TEntity> entities, bool IsSubmit = true)
        {
            Session.Update(entities);
            Session.Flush();
        }

        public async Task UpdateAsync(TEntity entity, bool IsSubmit = true)
        {
            await Session.UpdateAsync(entity);
            await Session.FlushAsync();
        }

        public async Task UpdateAsync(IEnumerable<TEntity> entities, bool IsSubmit = true)
        {
            await Session.UpdateAsync(entities);
            await Session.FlushAsync();
        }

        private string ToWhereString(IEnumerable<int> Ids)
        {
            StringBuilder stringBuilder = new StringBuilder();
            foreach (int id in Ids)
            {
                if (!string.IsNullOrWhiteSpace(stringBuilder.ToString()))
                {
                    stringBuilder.Append(",");
                }
                stringBuilder.Append(id);
            }
            return stringBuilder.ToString();
        }

        public TQueryableTable TableQueryable<TQueryableTable>()
        {
            throw new NotImplementedException();
        }
    }
}
